package com.cloud.api.websockt.handler;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.socket.WebSocketHandler;
import org.springframework.web.reactive.socket.WebSocketSession;

import com.alibaba.fastjson.JSONObject;
import com.cloud.api.foreign.IRoomService;
import com.cloud.api.user.service.UserService;
import com.cloud.api.util.JwtTokenUtil;
import com.cloud.api.websockt.message.PayLoadData;
import com.cloud.api.websockt.message.ResultData;
import com.cloud.cache.common.RedisCacheKeys;
import com.cloud.cache.service.RedisService;
import com.cloud.common.core.BMDataContext;
import com.cloud.common.util.jwt.IJWTInfo;
import com.cloud.model.PlayUserClient;

import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;

@Component
@Slf4j
public class GameEventHandler implements WebSocketHandler {

	@Autowired
	private JwtTokenUtil jwtTokenUtil;

	@Autowired
	private UserService userService;
	
	@Autowired
	private RedisService<PlayUserClient> redisService;
	
	@Autowired
	private IRoomService roomService;
	
	@Override
	public List<String> getSubProtocols() {
		return null;
	}

	/**
	 * WebSocketHandler 接口，实现该接口来处理 WebSokcet 消息。 handle(WebSocketSession session)
	 * 方法，接收 WebSocketSession 对象， 即获取客户端信息、发送消息和接收消息的操作对象。 receive() 方法，接收消息，使用 map
	 * 操作获取的 Flux 中包含的消息持续处理， 并拼接出返回消息 Flux 对象。 send() 方法，发送消息。消息为“服务端返回：jack， ->
	 * ”开头的。
	 * 
	 * @param webSocketSession
	 * @return
	 */

	@Override
	public Mono<Void> handle(WebSocketSession webSocketSession) {
		return webSocketSession.send(webSocketSession.receive().map(msg -> {
			String s = msg.getPayloadAsText();
			log.debug("s is {}", s);
			return s;
		}).map(payLoadString -> {
			PayLoadData pld = JSONObject.parseObject(payLoadString, PayLoadData.class);
			log.debug("pld is {}", pld);
			return pld;
		}).map(gameMsg -> {
			return handleGameData(gameMsg);
		}).map(msg -> {
			return webSocketSession.textMessage(msg);
		}));
	}

	private String handleGameData(PayLoadData data) {
		String token = data.getToken();
		IJWTInfo jwtInfo = jwtTokenUtil.getInfoFromToken(token);
		log.info("PayLoadData is {}", jwtInfo);
		String result = "";
		ResultData resultData = new ResultData(data);
		switch (data.getCommand()) {
		case "joinroom":
            this.onJoinRoom(jwtInfo);
            break;
		case "gamestatus":
			result = "游戏处理器处理命令成功！";
			break;
		default:
			break;
		}
		return JSONObject.toJSONString(resultData);
	}

	private void onJoinRoom(IJWTInfo jwtInfo) {
		/**
         * Token不为空，并且，验证Token有效，验证完毕即开始进行游戏撮合，房卡类型的
         * 1、大厅房间处理
         *    a、从房间队列里获取最近一条房间信息
         *    b、将token对应玩家加入到房间
         *    c、如果房间凑齐了玩家，则将房间从等待撮合队列中移除，放置到游戏中的房间信息，如果未凑齐玩家，继续扔到队列
         *    d、通知房间的所有人，有新玩家加入
         *    e、超时处理，增加AI进入房间
         *    f、事件驱动
         *    g、定时器处理
         * 2、房卡房间处理
         * 	  a、创建房间
         * 	  b、加入到等待中队列
         */
		
		
		//检查用户近期是否登录过
		String userId = jwtInfo.getId();
		userService.findByIdInCache(userId).map(playUserClient->{
			log.debug("client is {}",playUserClient);
			//心跳时间
			playUserClient.setTime(System.currentTimeMillis());
			/**
             * 更新当前玩家状态，在线|离线
             */
			playUserClient.setOnline(true);
			playUserClient.setStatus(BMDataContext.PlayerTypeEnum.NORMAL.toString());
			return playUserClient;
		}).map(client->{
			log.debug("client is {}",client);
			redisService.save(RedisCacheKeys.USER_KEY_HEAD+userId, client);
			return roomService.aquire(client);
		});
//            NettyClients.getInstance().putClient(userClient.getId(), beiMiClient);



//            BMDataContext.getGameEngine().gameRequest(userToken.getUserid(), beiMiClient.getPlayway(), beiMiClient.getRoom(), beiMiClient.getOrgi(), userClient, beiMiClient);
		
	}

	// 抢地主事件
	// public void onGameStatus(BeiMiClient beiMiClient) throws IOException {
	// Token userToken;
	// GameStatus gameStatus = new GameStatus();
	// gameStatus.setGamestatus(BMDataContext.GameStatusEnum.NOTREADY.toString());
	// if (beiMiClient != null && !StringUtils.isBlank(beiMiClient.getToken()) &&
	// (userToken = (Token)
	// CacheHelper.getApiUserCacheBean().getCacheObject(beiMiClient.getToken(),
	// beiMiClient.getOrgi())) != null) {
	// //鉴权完毕
	// PlayUserClient userClient = (PlayUserClient)
	// CacheHelper.getApiUserCacheBean().getCacheObject(userToken.getUserid(),
	// userToken.getOrgi());
	// if (userClient != null) {
	// gameStatus.setGamestatus(BMDataContext.GameStatusEnum.READY.toString());
	// String roomid = (String)
	// CacheHelper.getRoomMappingCacheBean().getCacheObject(userClient.getId(),
	// userClient.getOrgi());
	// if (!StringUtils.isBlank(roomid) &&
	// CacheHelper.getBoardCacheBean().getCacheObject(roomid, userClient.getId()) !=
	// null) {
	// gameStatus.setUserid(userClient.getId());
	// gameStatus.setOrgi(userClient.getOrgi());
	//
	// GameRoom gameRoom = (GameRoom)
	// CacheHelper.getGameRoomCacheBean().getCacheObject(roomid,
	// userClient.getOrgi());
	// GamePlayway gamePlayway = (GamePlayway)
	// CacheHelper.getSystemCacheBean().getCacheObject(gameRoom.getPlayway(),
	// userClient.getOrgi());
	// gameStatus.setGametype(gamePlayway.getCode());
	// gameStatus.setPlayway(gamePlayway.getId());
	// gameStatus.setGamestatus(BMDataContext.GameStatusEnum.PLAYING.toString());
	// if (gameRoom.isCardroom()) {
	// gameStatus.setCardroom(true);
	// }
	// }
	// }
	// } else {
	// gameStatus.setGamestatus(BMDataContext.GameStatusEnum.TIMEOUT.toString());
	// }
	// beiMiClient.sendEvent(BMDataContext.BEIMI_GAMESTATUS_EVENT, gameStatus);
	// }
}
